# If need to close all connections
lapply( dbListConnections( dbDriver( drv = "MySQL")), dbDisconnect)
This is a first pass exploration of different aspects of beer.
Dump this all into a MySQL database
style_collapsed column to reduce the number of levels of our outcome variable
grep through each beer’s style to determine if that style contains a keyword that qualifies it to be rolled into a collapsed stylestyle_collapsed columnhops and malts into a sparse matrix
Cluster: unsupervised k-means clsutering based on ABV, IBU, and SRM
style or style_collapsed from all the predictors including the total number of hops and malts per beerShort Aside
The question of what should be a predictor variable for style is a bit murky here. What should be fair game for predicting style and what shouldn’t? Characteristics of a beer that are defined by its style would seem to be “cheating” in a way.
This document compiled by querying the beer database I built, specifically by sourcing the file read_from_db.R. This is done for expediency’s sake, (the code below detailing how to get the beer, run in full in run_it.R, takes some time to execute).
Getting beer, the age-old dilemma
1:number_of_pages
number_of_pages to, e.g., 3 if we only want the first 3 pagesaddition parameter can be an empty string if nothing else is neededbase_url <- "http://api.brewerydb.com/v2"
key_preface <- "/?key="
paginated_request <- function(ep, addition) {
full_request <- NULL
first_page <- fromJSON(paste0(base_url, "/", ep, "/", key_preface, key
, "&p=1"))
number_of_pages <- ifelse(!(is.null(first_page$numberOfPages)),
first_page$numberOfPages, 1)
for (page in 1:number_of_pages) {
this_request <- fromJSON(paste0(base_url, "/", ep, "/", key_preface, key
, "&p=", page, addition),
flatten = TRUE)
this_req_unnested <- unnest_it(this_request) # <- request unnested here
print(this_req_unnested$currentPage)
full_request <- bind_rows(full_request, this_req_unnested[["data"]])
}
full_request
}
all_beer_raw <- paginated_request("beers", "&withIngredients=Y")
paginated_request() below
name nested within a column in the data portion of the response
name column doesn’t exist, it takes the first nested columnhops_name and malt_nameunnest_it <- function(df) {
unnested <- df
for(col in seq_along(df[["data"]])) {
if(! is.null(ncol(df[["data"]][[col]]))) {
if(! is.null(df[["data"]][[col]][["name"]])) {
unnested[["data"]][[col]] <- df[["data"]][[col]][["name"]]
} else {
unnested[["data"]][[col]] <- df[["data"]][[col]][[1]]
}
}
}
unnested
}
Collapse Styles
keywordsgrep through its style column to see if it contains any one of these keywordsstyle_collapsedstyle_collapsed is the last of those that appear in keywords
keywords after India Pale Ale and Pale Ale, an American Double India Pale Ale would get a style_collapsed of Double India Pale Alestyle, style_collapsed is just whatever’s in style; in other words, it doesn’t get collpsed into a bigger bucket
style_collapsedcollapse_styles <- function(df) {
keywords <- c("Lager", "Pale Ale", "India Pale Ale", "Double India Pale Ale", "India Pale Lager", "Hefeweizen", "Barrel-Aged","Wheat", "Pilsner", "Pilsener", "Amber", "Golden", "Blonde", "Brown", "Black", "Stout", "Porter", "Red", "Sour", "Kölsch", "Tripel", "Bitter", "Saison", "Strong Ale", "Barley Wine", "Dubbel", "Altbier")
for (beer in 1:nrow(df)) {
if (grepl(paste(keywords, collapse="|"), df$style[beer])) {
for (keyword in keywords) {
if(grepl(keyword, df$style[beer]) == TRUE) {
df$style_collapsed[beer] <- keyword
}
}
} else {
df$style_collapsed[beer] <- as.character(df$style[beer])
}
print(df$style_collapsed[beer])
}
return(df)
}
fct_collapseing those levelscollapse_further <- function(df) {
df[["style_collapsed"]] <- df[["style_collapsed"]] %>%
fct_collapse(
"Wheat" = c("Hefeweizen", "Wheat"),
"Pilsener" = c("Pilsner", "American-Style Pilsener") # pilsener == pilsner == pils
)
return(df)
}
Split out Ingredients
<ingredient>_name with this split_ingredients functionThis takes a vector of ingredients_to_split, so e.g. c("hops_name", "malt_name") and creates one column for each type of ingredient (hops_name_1, hops_name_2, etc.)
str_split on the ingredient and get a list backThen for each element in our list of split up ingredients, if it exists, we add it to the correct column in our df
split_ingredients <- function(df, ingredients_to_split) {
ncol_df <- ncol(df)
for (ingredient in ingredients_to_split) {
ingredient_split <- str_split(df[[ingredient]], ", ")
num_new_cols <- max(lengths(ingredient_split))
for (num in 1:num_new_cols) {
this_col <- ncol_df + 1
df[, this_col] <- NA
names(df)[this_col] <- paste0(ingredient, "_", num)
ncol_df <- ncol(df)
for (row in seq_along(ingredient_split)) {
if (!is.null(ingredient_split[[row]][num])) {
df[row, this_col] <- ingredient_split[[row]][num]
}
}
df[[names(df)[this_col]]] <- factor(df[[names(df)[this_col]]])
}
ncol_df <- ncol(df)
}
return(df)
}
Find the Most Popualar Styles
library(forcats)
# Pare down to only cases where style is not NA
beer_dat <- beer_necessities
beer_dat_pared <- beer_dat[complete.cases(beer_dat$style), ]
# Arrange beer dat by style popularity
style_popularity <- beer_dat_pared %>%
group_by(style) %>%
count() %>%
arrange(desc(n))
style_popularity
# Add a column that scales popularity
style_popularity <- bind_cols(style_popularity,
n_scaled = as.vector(scale(style_popularity$n)))
# Find styles that are above a z-score of 0
popular_styles <- style_popularity %>%
filter(n_scaled > 0)
# Pare dat down to only beers that fall into those styles
popular_beer_dat <- beer_dat_pared %>%
filter(
style %in% popular_styles$style
) %>%
droplevels() %>%
as_tibble()
nrow(popular_beer_dat)
# Find the centers (mean abv, ibu, srm) of the most popular styles
style_centers <- popular_beer_dat %>%
group_by(style_collapsed) %>%
add_count() %>%
summarise(
mean_abv = mean(abv, na.rm = TRUE),
mean_ibu = mean(ibu, na.rm = TRUE),
mean_srm = mean(srm, na.rm = TRUE),
n = median(n, na.rm = TRUE) # Median here only for summarise. Should be just the same as n
) %>%
arrange(desc(n)) %>%
drop_na() %>%
droplevels()
# Give some nicer names
style_centers_rename <- style_centers %>%
rename(
`Collapsed Style` = style_collapsed,
`Mean ABV` = mean_abv,
`Mean IBU` = mean_ibu,
`Mean SRM` = mean_srm,
`Numer of Beers` = n
)
Take a look at the table
kable(style_centers_rename)
| Collapsed Style | Mean ABV | Mean IBU | Mean SRM | Numer of Beers |
|---|---|---|---|---|
| India Pale Ale | 6.578468 | 66.04268 | 9.989313 | 6524 |
| Pale Ale | 5.695480 | 40.86930 | 8.890306 | 4280 |
| Stout | 7.991841 | 43.89729 | 36.300000 | 4238 |
| Wheat | 5.158040 | 17.47168 | 5.861842 | 3349 |
| Double India Pale Ale | 8.930599 | 93.48142 | 11.006873 | 2525 |
| Red | 5.742565 | 33.81127 | 16.178862 | 2521 |
| Lager | 5.453718 | 30.64361 | 8.457447 | 2230 |
| Saison | 6.400189 | 27.25114 | 7.053476 | 2167 |
| Blonde | 5.595298 | 22.39432 | 5.625000 | 2044 |
| Porter | 6.182049 | 33.25369 | 32.197605 | 1973 |
| Brown | 6.159212 | 32.21577 | 23.592000 | 1462 |
| Pilsener | 5.227593 | 33.51346 | 4.413462 | 1268 |
| Specialty Beer | 6.446402 | 33.77676 | 15.520548 | 1044 |
| Bitter | 5.322364 | 38.28175 | 12.460526 | 939 |
| Fruit Beer | 5.195222 | 19.24049 | 8.666667 | 905 |
| Herb and Spice Beer | 6.621446 | 27.77342 | 18.166667 | 872 |
| Sour | 6.224316 | 18.88869 | 10.040816 | 797 |
| Strong Ale | 8.826425 | 36.74233 | 22.547945 | 767 |
| Tripel | 9.029775 | 32.51500 | 7.680556 | 734 |
| Black | 6.958714 | 65.50831 | 31.080000 | 622 |
| Barley Wine | 10.781600 | 74.04843 | 19.561404 | 605 |
| Kölsch | 4.982216 | 23.37183 | 4.371795 | 593 |
| Barrel-Aged | 9.002506 | 39.15789 | 18.133333 | 540 |
| Other Belgian-Style Ales | 7.516318 | 37.55812 | 17.549020 | 506 |
| Pumpkin Beer | 6.712839 | 23.48359 | 17.918033 | 458 |
| Dubbel | 7.509088 | 25.05128 | 22.940000 | 399 |
| Scotch Ale | 7.620233 | 26.36909 | 24.222222 | 393 |
| German-Style Doppelbock | 8.045762 | 28.88692 | 25.696970 | 376 |
| Fruit Cider | 6.205786 | 25.60000 | 12.000000 | 370 |
| German-Style Märzen | 5.746102 | 25.63796 | 14.322581 | 370 |
Now that the munging is done, onto the main question: do natural clusters in beer align with style boundaries?
To get more granular with ingredients, we can split out each individual ingredient into its own column. If a beer or style contains that ingredient, its row gets a 1 in that ingredient column and a 0 otherwise.
From this, we can find the total number of hops and malts per grouper.
beer_necessitiesingredient_want: this can be hops, malt, or other ingredients like yeast if we pull that ingrouper: can be a vector of one or more things to group by, like beer name or stylepick_ingredient_get_beer <- function (ingredient_want, df, grouper) {
# ----------------------- Setup --------------------------- #
# We've already split ingredient number names out from the concatenated string into columns like `malt_name_1`,
# `malt_name_2`, etc. We need to find the range of these columns; there will be a different number of malt
# columns than hops columns, for instance. The first one will be `<ingredient>_name_1` and from this we can find
# the index of this column in our dataframe. We get the name of last one with the `get_last_ing_name_col()`
# function. Then we save a vector of all the ingredient column names in `ingredient_colnames`. It will stay
# constant even if the indices change when we select out certain columns.
# First ingredient
first_ingredient_name <- paste(ingredient_want, "_name_1", sep="")
first_ingredient_index <- which(colnames(df)==first_ingredient_name)
# Get the last ingredient
get_last_ing_name_col <- function(df) {
for (col in names(df)) {
if (grepl(paste(ingredient_want, "_name_", sep = ""), col) == TRUE) {
name_last_ing_col <- col
}
}
return(name_last_ing_col)
}
# Last ingredient
last_ingredient_name <- get_last_ing_name_col(df)
last_ingredient_index <- which(colnames(df)==last_ingredient_name)
# Vector of all the ingredient column names
ingredient_colnames <- names(df)[first_ingredient_index:last_ingredient_index]
# Non-ingredient column names we want to keep
to_keep_col_names <- c("cluster_assignment", "name", "abv", "ibu", "srm", "style", "style_collapsed")
# -------------------------------------------------------------------------------#
# Inside `gather_ingredients()` we take out superflous column names that are not in `to_keep_col_names` or one
# of the ingredient columns, find what the new ingredient column indices are, since they'll have changed after
# we pared down and then gather all of the ingredient columns (e.g., `hops_name_1`) into one long column,
# `ing_keys` and all the actual ingredient names (e.g., Cascade) into `ing_names`.
# ----------------------------- Gather columns --------------------------------- #
gather_ingredients <- function(df, cols_to_gather) {
to_keep_indices <- which(colnames(df) %in% to_keep_col_names)
selected_df <- df[, c(to_keep_indices, first_ingredient_index:last_ingredient_index)]
new_ing_indices <- which(colnames(selected_df) %in% cols_to_gather) # indices will have changed since we pared down
df_gathered <- selected_df %>%
gather_(
key_col = "ing_keys",
value_col = "ing_names",
gather_cols = colnames(selected_df)[new_ing_indices]
) %>%
mutate(
count = 1
)
df_gathered
}
beer_gathered <- gather_ingredients(df, ingredient_colnames) # ingredient colnames defined above function
# ------------------------------------------------------------------------------- #
# Next we get a vector of all ingredient levels and take out the one that's an empty string and
# use this vector of ingredient levels in `select_spread_cols()` below
# Get a vector of all ingredient levels
beer_gathered$ing_names <- factor(beer_gathered$ing_names)
ingredient_levels <- levels(beer_gathered$ing_names)
# Take out the level that's just an empty string
to_keep_levels <- !(c(1:length(ingredient_levels)) %in% which(ingredient_levels == ""))
ingredient_levels <- ingredient_levels[to_keep_levels]
beer_gathered$ing_names <- as.character(beer_gathered$ing_names)
# ----------------------------------------------------------------------------- #
# Then we spread the ingredient names: we take what was previously the `value` in our gathered dataframe, the
# actual ingredient names (Cascade, Centennial) and make that our `key`; it'll form the new column names. The
# new `value` is `value` is count; it'll populate the row cells. If a given row has a certain ingredient, it
# gets a 1 in the corresponding cell, an NA otherwise.
# We add a unique idenfitier for each row with `row`, which we'll drop later (see [Hadley's SO
# comment](https://stackoverflow.com/questions/25960394/unexpected-behavior-with-tidyr)).
# ------------------------------- Spread columns -------------------------------- #
spread_ingredients <- function(df) {
df_spread <- df %>%
mutate(
row = 1:nrow(df) # Add a unique idenfitier for each row which we'll need in order to spread; we'll drop this later
) %>%
spread(
key = ing_names,
value = count
)
return(df_spread)
}
beer_spread <- spread_ingredients(beer_gathered)
# ------------------------------------------------------------------------------- #
# ------------------------- Select only certain columns ------------------------- #
select_spread_cols <- function(df) {
to_keep_col_indices <- which(colnames(df) %in% to_keep_col_names)
to_keep_ingredient_indices <- which(colnames(df) %in% ingredient_levels)
to_keep_inds_all <- c(to_keep_col_indices, to_keep_ingredient_indices)
new_df <- df %>%
select_(
.dots = to_keep_inds_all
)
return(new_df)
}
beer_spread_selected <- select_spread_cols(beer_spread)
# ------------------------------------------------------------------------------- #
# Take out all rows that have no ingredients specified at all
inds_to_remove <- apply(beer_spread_selected[, first_ingredient_index:last_ingredient_index],
1, function(x) all(is.na(x)))
beer_spread_no_na <- beer_spread_selected[ !inds_to_remove, ]
# ----------------- Group ingredients by the grouper specified ------------------- #
# Then we do the final step and group by the groupers.
get_ingredients_per_grouper <- function(df, grouper = grouper) {
df_grouped <- df %>%
ungroup() %>%
group_by_(grouper)
not_for_summing <- which(colnames(df_grouped) %in% to_keep_col_names)
max_not_for_summing <- max(not_for_summing)
per_grouper <- df_grouped %>%
select(-c(abv, ibu, srm)) %>% # taking out temporarily
summarise_if(
is.numeric,
sum, na.rm = TRUE
# -c(abv, ibu, srm)
) %>%
mutate(
total = rowSums(.[(max_not_for_summing + 1):ncol(.)], na.rm = TRUE)
)
# Send total to the second position
per_grouper <- per_grouper %>%
select(
name, total, everything()
)
# Replace total column with more descriptive name: total_<ingredient>
names(per_grouper)[which(names(per_grouper) == "total")] <- paste0("total_", ingredient_want)
return(per_grouper)
}
# ------------------------------------------------------------------------------- #
ingredients_per_grouper <- get_ingredients_per_grouper(beer_spread_selected, grouper)
return(ingredients_per_grouper)
}
ingredient_want as first hops, then malt# Run the entire function with ingredient_want set to hops, grouping by name
ingredients_per_beer_hops <- pick_ingredient_get_beer(ingredient_want = "hops",
beer_necessities,
grouper = c("name", "style_collapsed"))
# Same for malt
ingredients_per_beer_malt <- pick_ingredient_get_beer(ingredient_want = "malt",
beer_necessities,
grouper = c("name", "style_collapsed"))
# Join those on our original dataframe by name
beer_ingredients_join_first_ingredient <- left_join(beer_necessities, ingredients_per_beer_hops,
by = "name")
beer_ingredients_join <- left_join(beer_ingredients_join_first_ingredient, ingredients_per_beer_malt,
by = "name")
# Take out some unnecessary columns
unnecessary_cols <- c("styleId", "abv_scaled", "ibu_scaled", "srm_scaled",
"hops_id", "malt_id", "glasswareId", "style.categoryId")
beer_ingredients_join <- beer_ingredients_join[, (! names(beer_ingredients_join) %in% unnecessary_cols)]
# If we also want to take out any of the malt_name_1, malt_name_2, etc. columns we can do this with a grep
more_unnecessary <- c("hops_name_|malt_name_")
beer_ingredients_join <-
beer_ingredients_join[, (! grepl(more_unnecessary, names(beer_ingredients_join)) == TRUE)]
# Reorder columns a bit
beer_ingredients_join <- beer_ingredients_join %>%
select(
id, name, total_hops, total_malt, everything(), -description
)
# And get a df that includes total_hops and total_malt but not all the other ingredient columns
beer_totals <- beer_ingredients_join %>%
select(
id, name, total_hops, total_malt, style, style_collapsed,
abv, ibu, srm, glass, hops_name, malt_name
)
Now we’re left with something of a sparse matrix of all the ingredients compared to all the beers
kable(beer_ingredients_join[1:20, ])
| id | name | total_hops | total_malt | style | abv | ibu | srm | glass | hops_name | malt_name | style_collapsed | #06300 | Admiral | Aged / Debittered Hops (Lambic) | Ahtanum | Alchemy | Amarillo | Amarillo Gold | Apollo | Aquila | Aramis | Argentine Cascade | Athanum | Aurora | Australian Dr. Rudi | Azacca | Azzeca | Belma | Bobek | Bramling Cross | Bravo | Brewer's Gold | Brewer's Gold (American) | Calypso | Cascade | Celeia | Centennial | Challenger | Chinook | Citra | Cluster | Cobb | Columbus | Columbus (Tomahawk) | Comet | Crystal | CTZ | Delta | East Kent Golding | El Dorado | Ella | Enigma | Equinox | Eureka | Experimental 05256 | Experimental 06277 | Falconer's Flight | First Gold | French Strisserspalt | French Triskel | Fuggle (American) | Fuggle (English) | Fuggles | Galaxy | Galena | German Magnum | German Mandarina Bavaria | German Opal | German Perle | German Polaris | German Select | German Tradition | Glacier | Golding (American) | Green Bullet | Hallertau Hallertauer Mittelfrüher | Hallertau Hallertauer Tradition | Hallertau Northern Brewer | Hallertauer (American) | Hallertauer Herkules | Hallertauer Hersbrucker | Hallertauer Perle | Hallertauer Select | Helga | Hop Extract | Hops | Horizon | Huell Melon | Idaho 7 | Jarrylo | Kent Goldings | Kohatu | Lemon Drop | Liberty | Magnum | Marynka | Meridian | Millenium | Mosaic | Motueka | Mount Hood | Mt. Rainier | Nelson Sauvin | New Zealand Hallertauer | New Zealand Motueka | New Zealand Sauvin | Newport | Noble | Northdown | Northern Brewer (American) | Nugget | Orbit | Pacific Gem | Pacific Jade | Pacifica | Palisades | Perle (American) | Phoenix | Pilgrim | Premiant | Pride of Ringwood | Rakau | Revolution | Saaz (American) | Saaz (Czech) | Santiam | Saphir (German Organic) | Simcoe | Sladek (Saaz) | Sorachi Ace | Southern Cross | Sovereign | Spalt | Spalt Select | Spalt Spalter | Sterling | Sticklebract | Strisselspalt | Styrian Aurora | Styrian Bobeks | Styrian Goldings | Summit | Super Galena | Target | Tettnang Tettnanger | Tettnanger (American) | Tomahawk | Topaz | Tradition | Ultra | Vanguard | Vic Secret | Waimea | Wakatu | Warrior | Willamette | Yakima Willamette | Zeus | Zythos | Abbey Malt | Acidulated Malt | Amber Malt | Aromatic Malt | Asheburne Mild Malt | Bamberg Smoked Malt | Barley - Black | Barley - Flaked | Barley - Lightly Roasted | Barley - Malted | Barley - Raw | Barley - Roasted | Barley - Roasted/De-husked | Beechwood Smoked | Belgian Pale | Belgian Pilsner | Biscuit Malt | Black Malt | Black Malt - Debittered | Black Malt - Organic | Black Patent | Black Roast | Blackprinz Malt | Blue Agave Nectar | Blue Corn | Bonlander | Briess 2-row Chocolate Malt | Briess Blackprinz Malt | British Pale Malt | Brown Malt | Brown Sugar | Buckwheat - Roasted | C-15 | Canada 2-Row Silo | Cane Sugar | Cara Malt | CaraAmber | CaraAroma | CaraBrown | Carafa I | Carafa II | Carafa III | Carafa Special | CaraFoam | CaraHell | Caramel/Crystal Malt | Caramel/Crystal Malt - Dark | Caramel/Crystal Malt - Extra Dark | Caramel/Crystal Malt - Heritage | Caramel/Crystal Malt - Light | Caramel/Crystal Malt - Medium | Caramel/Crystal Malt - Organic | Caramel/Crystal Malt 10L | Caramel/Crystal Malt 120L | Caramel/Crystal Malt 150L | Caramel/Crystal Malt 15L | Caramel/Crystal Malt 20L | Caramel/Crystal Malt 300L | Caramel/Crystal Malt 30L | Caramel/Crystal Malt 40L | Caramel/Crystal Malt 45L | Caramel/Crystal Malt 50L | Caramel/Crystal Malt 55L | Caramel/Crystal Malt 60L | Caramel/Crystal Malt 70L | Caramel/Crystal Malt 75L | Caramel/Crystal Malt 80L | Caramel/Crystal Malt 85L | Caramel/Crystal Malt 8L | Caramel/Crystal Malt 90L | CaraMunich | CaraMunich 120L | CaraMunich 20L | CaraMunich 40L | CaraMunich 60L | CaraMunich I | CaraMunich II | CaraMunich III | CaraPils/Dextrin Malt | CaraRed | CaraRye | CaraStan | CaraVienne Malt | CaraWheat | Carolina Rye Malt | Cereal | Cherry Smoked | Cherrywood Smoke Malt | Chit Malt | Chocolate Malt | Chocolate Rye Malt | Chocolate Wheat Malt | Coffee Malt | Corn | Corn - Field | Corn - Flaked | Corn Grits | Crisp 120 | Crisp 77 | Crystal 77 | Dark Chocolate | Dememera Sugar | Dextrin Malt | Dextrose Syrup | Extra Special Malt | Fawcett Crystal Rye | Fawcett Rye | German Cologne | Gladfield Pale | Glen Eagle Maris Otter | Golden Promise | Harrington 2-Row Base Malt | High Fructose Corn Syrup | Honey | Honey Malt | Hugh Baird Pale Ale Malt | Kiln Amber | Lactose | Lager Malt | Malt Extract | Malted Rye | Malto Franco-Belge Pils Malt | Maple Syrup | Maris Otter | Melanoidin Malt | Metcalfe | Midnight Wheat | Mild Malt | Millet | Munich Malt | Munich Malt - Dark | Munich Malt - Light | Munich Malt - Organic | Munich Malt - Smoked | Munich Malt - Type I | Munich Malt - Type II | Munich Malt 10L | Munich Malt 20L | Munich Malt 40L | Munich Wheat | Oats - Flaked | Oats - Golden Naked | Oats - Malted | Oats - Rolled | Oats - Steel Cut (Pinhead Oats) | Oats - Toasted | Pale Chocolate Malt | Pale Malt | Pale Malt - Halcyon | Pale Malt - Optic | Pale Malt - Organic | Pale Wheat | Palev | Pearl Malt | Peated Malt - Smoked | Piloncillo | Pilsner Malt | Pilsner Malt - Organic | Rahr 2-Row Malt | Rahr Special Pale | Rauchmalz | Rice | Rice - Flaked | Rice - Hulls | Rice - Red | Rice - White | Roast Malt | Rye - Flaked | Rye Malt | Samuel Adams two-row pale malt blend | Six-Row Pale Malt | Smoked Malt | Special B Malt | Special Roast | Special W Malt | Spelt Malt | Sugar (Albion) | Toasted Malt | Torrefied Wheat | Two-Row Barley Malt | Two-Row Pale Malt | Two-Row Pale Malt - Organic | Two-Row Pale Malt - Toasted | Two-Row Pilsner Malt | Two-Row Pilsner Malt - Belgian | Two-Row Pilsner Malt - Germany | Victory Malt | Vienna Malt | Weyermann Rye | Wheat - Flaked | Wheat - Raw | Wheat - Red | Wheat - Toasted | Wheat - Torrified | Wheat Malt | Wheat Malt - Dark | Wheat Malt - German | Wheat Malt - Light | Wheat Malt - Organic | Wheat Malt - Red | Wheat Malt - Smoked | Wheat Malt - White | White Wheat | Wyermann Vienna |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| cBLTUw | "18" Imperial IPA 2 | 0 | 0 | American-Style Imperial Stout | 11.10 | NA | 33 | Pint | NA | NA | Stout | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| ZsQEJt | "633" American Pale Ale | 0 | 0 | American-Style Pale Ale | 6.33 | 25.0 | NA | NA | NA | NA | Pale Ale | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| tmEthz | "Admiral" Stache | 2 | 4 | Baltic-Style Porter | 7.00 | 23.0 | 37 | Pint | Perle (American), Saaz (American) | Barley - Malted, Chocolate Malt, Munich Malt, Oats - Flaked | Porter | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| b7SfHG | "Ah Me Joy" Porter | 0 | 0 | Robust Porter | 5.40 | 51.0 | 40 | NA | NA | NA | Porter | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| zcJMId | "Alternating Currant" Sour | 0 | 0 | American-Style Sour Ale | 4.80 | 12.0 | NA | NA | NA | NA | Sour | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| UM8GL6 | "B" Street Pineapple Blonde | 0 | 0 | Golden or Blonde Ale | 4.60 | NA | 5 | NA | NA | NA | Blonde | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| NIaY9C | "B.B. Rodriguez" Double Brown | 0 | 0 | American-Style Brown Ale | 8.50 | 30.0 | NA | NA | NA | NA | Brown | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| PBEXhV | "Bison Eye Rye" Pale Ale | 2 of 4 Part Pale Ale Series | 0 | 0 | American-Style Pale Ale | 5.80 | 51.0 | 8 | NA | NA | NA | Pale Ale | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| wRmmdv | "California Crude" Black IPA | 0 | 0 | American-Style Black Ale | 7.60 | 80.0 | NA | NA | NA | NA | Black | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| EPYNpW | "C’est Noir" Imperial Stout | 0 | 0 | British-Style Imperial Stout | 10.80 | 70.0 | NA | NA | NA | NA | Stout | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| AXmvOd | "Dust Up" Cloudy Pale Ale | 1 of 4 Part Pale Ale Series | 0 | 0 | American-Style Pale Ale | 5.40 | 54.0 | 11 | NA | NA | NA | Pale Ale | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| c5pZg5 | "EVL1" Imperial Red Ale | 0 | 0 | Imperial Red Ale | 10.40 | 64.0 | NA | NA | NA | NA | Red | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| xBKAka | "Galactic Wrath" IPA | 0 | 0 | American-Style India Pale Ale | 7.50 | 75.0 | NA | NA | NA | NA | India Pale Ale | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Hr5A0t | "God Country" Kolsch | 0 | 0 | German-Style Kölsch / Köln-Style Kölsch | 5.60 | 28.2 | 5 | NA | NA | NA | Kölsch | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| UjFyXJ | "Hey Victor" Smoked Porter | 0 | 0 | Smoke Beer (Lager or Ale) | 5.50 | NA | NA | NA | NA | NA | Lager | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 5UcMBc | "Ignition" IPA | 0 | 0 | American-Style India Pale Ale | 6.60 | 45.0 | NA | Pint | NA | NA | India Pale Ale | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| mrVjY4 | "Jemez Field Notes" Golden Lager | 0 | 0 | Golden or Blonde Ale | 4.90 | 20.0 | 5 | NA | NA | NA | Blonde | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 54rSgo | "Jemmy Dean" Breakfast Stout | 0 | 0 | Sweet or Cream Stout | NA | NA | NA | Pint | NA | NA | Stout | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| JsKjkk | "Mauvaises Choses" | 0 | 0 | Belgian-Style Pale Strong Ale | 7.00 | 30.0 | NA | Tulip | NA | NA | Strong Ale | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| b7WWL6 | "Mike Saw a Sasquatch" Session Ale | 2 | 2 | Golden or Blonde Ale | 4.70 | 26.0 | NA | Pint | Cascade, Sterling | Honey Malt, Two-Row Pale Malt | Blonde | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
We K-means cluster beers based on certain numeric predictor variables.
Prep
library(NbClust)
cluster_it <- function(df, preds, to_scale, resp, n_centers) {
df_for_clustering <- df %>%
select_(.dots = c(response_vars, cluster_on)) %>%
na.omit() %>%
filter(
abv < 20 & abv > 3
) %>%
filter(
ibu < 200
)
df_all_preds <- df_for_clustering %>%
select_(.dots = preds)
df_preds_scale <- df_all_preds %>%
select_(.dots = to_scale) %>%
rename(
abv_scaled = abv,
ibu_scaled = ibu,
srm_scaled = srm
) %>%
scale() %>%
as_tibble()
df_preds <- bind_cols(df_preds_scale, df_all_preds[, (!names(df_all_preds) %in% to_scale)])
df_outcome <- df_for_clustering %>%
select_(.dots = resp) %>%
na.omit()
set.seed(9)
clustered_df_out <- kmeans(x = df_preds, centers = n_centers, trace = TRUE)
clustered_df <- as_tibble(data.frame(
cluster_assignment = factor(clustered_df_out$cluster),
df_outcome, df_preds,
df_for_clustering %>% select(abv, ibu, srm)))
return(clustered_df)
}
Cluster
First we’ll run the fuction with 10 centers, and cluster on the predictors ABV, IBU, SRM, total_hops, and total_malt.
cluster_on <- c("abv", "ibu", "srm", "total_hops", "total_malt")
to_scale <- c("abv", "ibu", "srm", "total_hops", "total_malt")
response_vars <- c("name", "style", "style_collapsed")
clustered_beer <- cluster_it(df = beer_totals,
preds = cluster_on,
to_scale = to_scale,
resp = response_vars,
n_centers = 10)
KMNS(*, k=10): iter= 1, indx=5
QTRAN(): istep=4472, icoun=1
QTRAN(): istep=8944, icoun=84
QTRAN(): istep=13416, icoun=31
QTRAN(): istep=17888, icoun=310
QTRAN(): istep=22360, icoun=444
QTRAN(): istep=26832, icoun=3571
KMNS(*, k=10): iter= 2, indx=28
QTRAN(): istep=4472, icoun=3
QTRAN(): istep=8944, icoun=26
QTRAN(): istep=13416, icoun=0
QTRAN(): istep=17888, icoun=45
QTRAN(): istep=22360, icoun=37
QTRAN(): istep=26832, icoun=170
QTRAN(): istep=31304, icoun=45
QTRAN(): istep=35776, icoun=64
QTRAN(): istep=40248, icoun=692
KMNS(*, k=10): iter= 3, indx=6
QTRAN(): istep=4472, icoun=16
QTRAN(): istep=8944, icoun=36
QTRAN(): istep=13416, icoun=318
QTRAN(): istep=17888, icoun=1114
QTRAN(): istep=22360, icoun=1628
QTRAN(): istep=26832, icoun=1518
KMNS(*, k=10): iter= 4, indx=227
QTRAN(): istep=4472, icoun=560
QTRAN(): istep=8944, icoun=1426
QTRAN(): istep=13416, icoun=401
KMNS(*, k=10): iter= 5, indx=4472
Head of the clustering data
kable(clustered_beer[1:20, ])
| cluster_assignment | name | style | style_collapsed | abv_scaled | ibu_scaled | srm_scaled | total_hops | total_malt | abv | ibu | srm |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 3 | "Admiral" Stache | Baltic-Style Porter | Porter | 0.2915030 | -0.6641211 | 2.1990458 | 0.4954773 | 1.1342326 | 7.0 | 23.0 | 37 |
| 3 | "Ah Me Joy" Porter | Robust Porter | Porter | -0.5813196 | 0.4600343 | 2.4832200 | -0.1956564 | -0.2062241 | 5.4 | 51.0 | 40 |
| 10 | "Bison Eye Rye" Pale Ale | 2 of 4 Part Pale Ale Series | American-Style Pale Ale | Pale Ale | -0.3631139 | 0.4600343 | -0.5479716 | -0.1956564 | -0.2062241 | 5.8 | 51.0 | 8 |
| 10 | "Dust Up" Cloudy Pale Ale | 1 of 4 Part Pale Ale Series | American-Style Pale Ale | Pale Ale | -0.5813196 | 0.5804795 | -0.2637974 | -0.1956564 | -0.2062241 | 5.4 | 54.0 | 11 |
| 2 | "God Country" Kolsch | German-Style Kölsch / Köln-Style Kölsch | Kölsch | -0.4722168 | -0.4553494 | -0.8321458 | -0.1956564 | -0.2062241 | 5.6 | 28.2 | 5 |
| 2 | "Jemez Field Notes" Golden Lager | Golden or Blonde Ale | Blonde | -0.8540767 | -0.7845663 | -0.8321458 | -0.1956564 | -0.2062241 | 4.9 | 20.0 | 5 |
| 2 | #10 Hefewiezen | South German-Style Hefeweizen / Hefeweissbier | Wheat | -0.7449738 | -1.1459020 | -0.9268705 | -0.1956564 | -0.2062241 | 5.1 | 11.0 | 4 |
| 2 | #9 | American-Style Pale Ale | Pale Ale | -0.7449738 | -0.7845663 | -0.4532468 | 0.4954773 | 0.4640043 | 5.1 | 20.0 | 9 |
| 2 | #KoLSCH | German-Style Kölsch / Köln-Style Kölsch | Kölsch | -0.9086281 | -0.5035275 | -1.0215953 | -0.1956564 | -0.2062241 | 4.8 | 27.0 | 3 |
| 2 | 'Inappropriate' Cream Ale | American-Style Cream Ale or Lager | Lager | -0.6358710 | -0.8648631 | -0.8321458 | -0.1956564 | -0.2062241 | 5.3 | 18.0 | 5 |
| 10 | 'tis the Saison | French & Belgian-Style Saison | Saison | 0.2915030 | -0.3830822 | -0.6426963 | -0.1956564 | -0.2062241 | 7.0 | 30.0 | 7 |
| 2 | (306) URBAN WHEAT BEER | Belgian-Style White (or Wit) / Belgian-Style Wheat | Wheat | -0.7995252 | -0.7845663 | -0.4532468 | -0.1956564 | -0.2062241 | 5.0 | 20.0 | 9 |
| 7 | (512) ALT | German-Style Altbier | Altbier | -0.2540111 | -0.1421918 | 0.6834500 | 0.1499105 | 0.7991185 | 6.0 | 36.0 | 21 |
| 7 | (512) Bruin (A.K.A. Brown Bear) | American-Style Brown Ale | Brown | 0.6188115 | -0.3830822 | 0.6834500 | 0.1499105 | 1.1342326 | 7.6 | 30.0 | 21 |
| 9 | (512) FOUR | Strong Ale | Strong Ale | 0.5642601 | -0.1823402 | -0.5479716 | 0.8410441 | 1.1342326 | 7.5 | 35.0 | 8 |
| 5 | (512) IPA | American-Style India Pale Ale | India Pale Ale | 0.2915030 | 1.0221120 | -0.5479716 | 0.8410441 | 0.7991185 | 7.0 | 65.0 | 8 |
| 9 | (512) ONE | Belgian-Style Pale Strong Ale | Strong Ale | 0.8370171 | -0.7042695 | -0.5479716 | -0.1956564 | 0.4640043 | 8.0 | 22.0 | 8 |
| 10 | (512) Pale | American-Style Pale Ale | Pale Ale | -0.2540111 | -0.3830822 | -0.6426963 | 0.8410441 | 0.7991185 | 6.0 | 30.0 | 7 |
| 6 | (512) SIX | Belgian-Style Dubbel | Dubbel | 0.5642601 | -0.5838243 | 1.3465231 | 0.4954773 | 0.7991185 | 7.5 | 25.0 | 28 |
| 9 | (512) THREE | Belgian-Style Tripel | Tripel | 1.6552883 | -0.7042695 | -0.3585221 | 0.1499105 | 0.7991185 | 9.5 | 22.0 | 10 |
Join the clustered beer on beer_ingredients_join
beer_ingredients_join_clustered <- left_join(beer_ingredients_join, clustered_beer,
by = "name")
A table of cluster counts broken down by style
cluster_table_counts <- table(style = clustered_beer$style_collapsed, cluster = clustered_beer$cluster_assignment)
kable(cluster_table_counts)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
|---|---|---|---|---|---|---|---|---|---|---|
| Adambier | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Altbier | 0 | 0 | 1 | 0 | 2 | 1 | 11 | 0 | 0 | 7 |
| Amber | 0 | 9 | 0 | 0 | 1 | 0 | 4 | 0 | 0 | 3 |
| American-Style Malt Liquor | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| American-Style Märzen / Oktoberfest | 0 | 5 | 0 | 0 | 0 | 0 | 6 | 11 | 1 | 2 |
| Apple Wine | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Bamberg-Style Bock Rauchbier | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| Bamberg-Style Helles Rauchbier | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Bamberg-Style Märzen Rauchbier | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 |
| Bamberg-Style Weiss (Smoke) Rauchbier (Dunkel or Helles) | 0 | 2 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
| Barley Wine | 28 | 0 | 0 | 19 | 2 | 2 | 0 | 0 | 11 | 0 |
| Barrel-Aged | 9 | 2 | 3 | 2 | 1 | 8 | 4 | 0 | 16 | 3 |
| Belgian-style Fruit Beer | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Fruit Lambic | 0 | 0 | 0 | 0 | 1 | 1 | 2 | 0 | 0 | 0 |
| Belgian-Style Gueuze Lambic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Lambic | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Quadrupel | 10 | 0 | 0 | 0 | 0 | 9 | 0 | 0 | 8 | 0 |
| Belgian-Style Table Beer | 0 | 5 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| Bitter | 1 | 15 | 0 | 0 | 2 | 1 | 22 | 0 | 1 | 38 |
| Black | 0 | 0 | 8 | 4 | 6 | 24 | 1 | 0 | 0 | 0 |
| Blonde | 0 | 113 | 1 | 0 | 1 | 1 | 4 | 0 | 19 | 21 |
| Braggot | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
| Brett Beer | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 2 | 2 |
| Brown | 2 | 8 | 28 | 1 | 6 | 11 | 90 | 0 | 0 | 2 |
| California Common Beer | 0 | 1 | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 8 |
| Chili Pepper Beer | 0 | 5 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 3 |
| Chocolate / Cocoa-Flavored Beer | 0 | 1 | 3 | 0 | 0 | 0 | 2 | 0 | 0 | 2 |
| Coffee-Flavored Beer | 0 | 0 | 9 | 0 | 2 | 8 | 1 | 0 | 0 | 0 |
| Common Cider | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Common Perry | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Contemporary Gose | 0 | 9 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Cyser (Apple Melomel) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Dark American-Belgo-Style Ale | 0 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 0 |
| Dortmunder / European-Style Export | 0 | 3 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 4 |
| Double India Pale Ale | 5 | 0 | 0 | 179 | 40 | 3 | 0 | 0 | 5 | 0 |
| Dry Mead | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Dubbel | 0 | 0 | 2 | 0 | 1 | 13 | 15 | 0 | 10 | 0 |
| Dutch-Style Kuit, Kuyt or Koyt | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| Energy Enhanced Malt Beverage | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| English Cider | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| English-Style Dark Mild Ale | 0 | 1 | 2 | 0 | 0 | 1 | 3 | 0 | 0 | 0 |
| English-Style Pale Mild Ale | 0 | 6 | 1 | 0 | 1 | 0 | 4 | 0 | 0 | 2 |
| English-Style Summer Ale | 0 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| European-Style Dark / Münchner Dunkel | 0 | 0 | 2 | 0 | 0 | 0 | 8 | 0 | 0 | 0 |
| Field Beer | 0 | 1 | 0 | 0 | 1 | 0 | 4 | 0 | 0 | 5 |
| Flavored Malt Beverage | 0 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| French Cider | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| French-Style Bière de Garde | 0 | 1 | 0 | 0 | 0 | 0 | 4 | 0 | 6 | 3 |
| Fresh "Wet" Hop Ale | 0 | 0 | 0 | 0 | 8 | 0 | 0 | 0 | 0 | 6 |
| Fruit Beer | 1 | 36 | 2 | 0 | 4 | 0 | 6 | 0 | 5 | 2 |
| Fruit Cider | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| German-Style Doppelbock | 0 | 0 | 2 | 0 | 0 | 13 | 5 | 0 | 9 | 0 |
| German-Style Eisbock | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| German-Style Heller Bock/Maibock | 0 | 1 | 1 | 0 | 1 | 0 | 6 | 0 | 4 | 9 |
| German-Style Leichtbier | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| German-Style Leichtes Weizen / Weissbier | 0 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| German-Style Märzen | 0 | 8 | 0 | 0 | 0 | 0 | 10 | 11 | 0 | 1 |
| German-Style Oktoberfest / Wiesen (Meadow) | 0 | 3 | 0 | 0 | 0 | 0 | 2 | 3 | 1 | 1 |
| German-Style Rye Ale (Roggenbier) with or without Yeast | 0 | 1 | 1 | 0 | 0 | 1 | 2 | 0 | 0 | 0 |
| German-Style Schwarzbier | 0 | 0 | 14 | 0 | 0 | 1 | 3 | 0 | 0 | 0 |
| Ginjo Beer or Sake-Yeast Beer | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Gluten-Free Beer | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
| Grodziskie | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Herb and Spice Beer | 1 | 12 | 9 | 0 | 7 | 6 | 12 | 0 | 4 | 4 |
| Historical Beer | 0 | 6 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
| India Pale Ale | 0 | 5 | 3 | 38 | 402 | 8 | 5 | 15 | 2 | 99 |
| Kellerbier (Cellar beer) or Zwickelbier - Ale | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 |
| Kölsch | 0 | 67 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 3 |
| Lager | 1 | 132 | 6 | 6 | 24 | 8 | 51 | 0 | 9 | 30 |
| Leipzig-Style Gose | 0 | 12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| Metheglin | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Mixed Culture Brett Beer | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| Münchner (Munich)-Style Helles | 0 | 32 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| New England Cider | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Non-Alcoholic (Beer) Malt Beverages | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Old Ale | 7 | 0 | 0 | 0 | 1 | 4 | 2 | 0 | 5 | 1 |
| Open Category Mead | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Other Belgian-Style Ales | 0 | 3 | 4 | 1 | 8 | 5 | 7 | 0 | 6 | 5 |
| Other Fruit Melomel | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Other Specialty Cider or Perry | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Pale Ale | 1 | 52 | 1 | 1 | 51 | 5 | 28 | 19 | 11 | 229 |
| Pale American-Belgo-Style Ale | 0 | 1 | 0 | 0 | 3 | 0 | 1 | 0 | 1 | 4 |
| Pilsener | 0 | 69 | 0 | 1 | 4 | 1 | 1 | 0 | 1 | 59 |
| Porter | 1 | 0 | 121 | 0 | 0 | 32 | 28 | 0 | 1 | 1 |
| Pumpkin Beer | 1 | 7 | 5 | 0 | 0 | 4 | 18 | 0 | 8 | 3 |
| Pyment (Grape Melomel) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Red | 0 | 25 | 15 | 13 | 28 | 13 | 125 | 7 | 7 | 40 |
| Saison | 0 | 53 | 3 | 0 | 2 | 1 | 7 | 0 | 31 | 42 |
| Scotch Ale | 0 | 0 | 4 | 0 | 0 | 12 | 9 | 0 | 7 | 1 |
| Scottish-Style Export Ale | 0 | 1 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | 0 |
| Scottish-Style Heavy Ale | 0 | 0 | 1 | 0 | 0 | 7 | 2 | 0 | 4 | 0 |
| Scottish-Style Light Ale | 0 | 1 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 |
| Semi-Sweet Mead | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Session Beer | 0 | 17 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 18 |
| Sour | 1 | 19 | 2 | 0 | 1 | 4 | 4 | 0 | 2 | 4 |
| South German-Style Bernsteinfarbenes Weizen / Weissbier | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| South German-Style Dunkel Weizen / Dunkel Weissbier | 0 | 0 | 0 | 0 | 0 | 1 | 13 | 0 | 1 | 0 |
| South German-Style Kristall Weizen / Kristall Weissbier | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| South German-Style Weizenbock / Weissbock | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 1 |
| Specialty Beer | 0 | 15 | 9 | 1 | 5 | 5 | 14 | 0 | 11 | 5 |
| Stout | 27 | 2 | 114 | 0 | 1 | 50 | 3 | 0 | 3 | 3 |
| Strong Ale | 6 | 0 | 2 | 4 | 3 | 16 | 4 | 0 | 45 | 2 |
| Sweet Mead | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Traditional German-Style Bock | 0 | 1 | 4 | 0 | 0 | 3 | 11 | 0 | 2 | 5 |
| Traditional Perry | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Tripel | 1 | 0 | 0 | 2 | 0 | 3 | 0 | 0 | 58 | 1 |
| Wheat | 0 | 266 | 3 | 0 | 4 | 1 | 13 | 0 | 12 | 18 |
| Wild Beer | 0 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
Plot the clusters. There are 3 axes: ABV, IBU, and SRM, so we choose two at a time.
clustered_beer_plot_abv_ibu <- ggplot(data = clustered_beer, aes(x = abv, y = ibu, colour = cluster_assignment)) +
geom_jitter() + theme_minimal() +
ggtitle("k-Means Clustering of Beer by ABV, IBU, SRM") +
labs(x = "ABV", y = "IBU") +
labs(colour = "Cluster Assignment")
clustered_beer_plot_abv_ibu
clustered_beer_plot_abv_srm <- ggplot(data = clustered_beer, aes(x = abv, y = srm, colour = cluster_assignment)) +
geom_jitter() + theme_minimal() +
ggtitle("k-Means Clustering of Beer by ABV, IBU, SRM") +
labs(x = "ABV", y = "SRM") +
labs(colour = "Cluster Assignment")
clustered_beer_plot_abv_srm
Now we can add in the style centers (means) for each style_collapsed and label it.
library(ggrepel)
abv_ibu_clusters_vs_style_centers <- ggplot() +
geom_point(data = clustered_beer,
aes(x = abv, y = ibu, colour = cluster_assignment), alpha = 0.5) +
geom_point(data = style_centers,
aes(mean_abv, mean_ibu), colour = "black") +
geom_text_repel(data = style_centers, aes(mean_abv, mean_ibu, label = style_collapsed),
box.padding = unit(0.45, "lines"),
family = "Calibri",
label.size = 0.3) +
ggtitle("Popular Styles vs. k-Means Clustering of Beer by ABV, IBU, SRM") +
labs(x = "ABV", y = "IBU") +
labs(colour = "Cluster Assignment") +
theme_bw()
abv_ibu_clusters_vs_style_centers
The clustering above used a smaller number of clusters (10) than there are styles_collapsed. That makes it difficult to determine whether a given style fits snugly into a cluster or not.
Cluster on just certain selected styles
We’ll take five very distinct collapsed styles and re-run the clustering on beers that fall into these categories. These styles were intentionally chosen because they are quite distinct: Blonde, IPA, Stout, Tripel, Wheat. Arguably, of these five styles Blondes and Wheats are the closest
styles_to_keep <- c("Blonde", "India Pale Ale", "Stout", "Tripel", "Wheat")
bt_certain_styles <- beer_totals %>%
filter(
style_collapsed %in% styles_to_keep
)
cluster_on <- c("abv", "ibu", "srm", "total_hops", "total_malt")
to_scale <- c("abv", "ibu", "srm", "total_hops", "total_malt")
response_vars <- c("name", "style", "style_collapsed")
certain_styles_clustered <- cluster_it(df = bt_certain_styles,
preds = cluster_on,
to_scale = to_scale,
resp = response_vars,
n_centers = 5)
KMNS(*, k=5): iter= 1, indx=4
QTRAN(): istep=1322, icoun=2
QTRAN(): istep=2644, icoun=20
QTRAN(): istep=3966, icoun=96
QTRAN(): istep=5288, icoun=0
QTRAN(): istep=6610, icoun=13
QTRAN(): istep=7932, icoun=285
KMNS(*, k=5): iter= 2, indx=13
QTRAN(): istep=1322, icoun=147
QTRAN(): istep=2644, icoun=138
QTRAN(): istep=3966, icoun=20
QTRAN(): istep=5288, icoun=599
KMNS(*, k=5): iter= 3, indx=20
QTRAN(): istep=1322, icoun=146
QTRAN(): istep=2644, icoun=617
KMNS(*, k=5): iter= 4, indx=1322
style_centers_certain_styles <- style_centers %>%
filter(style_collapsed %in% styles_to_keep)
Table of style vs. cluster.
kable(table(style = certain_styles_clustered$style_collapsed, cluster = certain_styles_clustered$cluster_assignment))
| 1 | 2 | 3 | 4 | 5 | |
|---|---|---|---|---|---|
| Adambier | 0 | 0 | 0 | 0 | 0 |
| Altbier | 0 | 0 | 0 | 0 | 0 |
| Amber | 0 | 0 | 0 | 0 | 0 |
| American-Style Malt Liquor | 0 | 0 | 0 | 0 | 0 |
| American-Style Märzen / Oktoberfest | 0 | 0 | 0 | 0 | 0 |
| Apple Wine | 0 | 0 | 0 | 0 | 0 |
| Bamberg-Style Bock Rauchbier | 0 | 0 | 0 | 0 | 0 |
| Bamberg-Style Helles Rauchbier | 0 | 0 | 0 | 0 | 0 |
| Bamberg-Style Märzen Rauchbier | 0 | 0 | 0 | 0 | 0 |
| Bamberg-Style Weiss (Smoke) Rauchbier (Dunkel or Helles) | 0 | 0 | 0 | 0 | 0 |
| Barley Wine | 0 | 0 | 0 | 0 | 0 |
| Barrel-Aged | 0 | 0 | 0 | 0 | 0 |
| Belgian-style Fruit Beer | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Fruit Lambic | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Gueuze Lambic | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Lambic | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Quadrupel | 0 | 0 | 0 | 0 | 0 |
| Belgian-Style Table Beer | 0 | 0 | 0 | 0 | 0 |
| Bitter | 0 | 0 | 0 | 0 | 0 |
| Black | 0 | 0 | 0 | 0 | 0 |
| Blonde | 1 | 142 | 1 | 0 | 16 |
| Braggot | 0 | 0 | 0 | 0 | 0 |
| Brett Beer | 0 | 0 | 0 | 0 | 0 |
| Brown | 0 | 0 | 0 | 0 | 0 |
| California Common Beer | 0 | 0 | 0 | 0 | 0 |
| Chili Pepper Beer | 0 | 0 | 0 | 0 | 0 |
| Chocolate / Cocoa-Flavored Beer | 0 | 0 | 0 | 0 | 0 |
| Coffee-Flavored Beer | 0 | 0 | 0 | 0 | 0 |
| Common Cider | 0 | 0 | 0 | 0 | 0 |
| Common Perry | 0 | 0 | 0 | 0 | 0 |
| Contemporary Gose | 0 | 0 | 0 | 0 | 0 |
| Cyser (Apple Melomel) | 0 | 0 | 0 | 0 | 0 |
| Dark American-Belgo-Style Ale | 0 | 0 | 0 | 0 | 0 |
| Dortmunder / European-Style Export | 0 | 0 | 0 | 0 | 0 |
| Double India Pale Ale | 0 | 0 | 0 | 0 | 0 |
| Dry Mead | 0 | 0 | 0 | 0 | 0 |
| Dubbel | 0 | 0 | 0 | 0 | 0 |
| Dutch-Style Kuit, Kuyt or Koyt | 0 | 0 | 0 | 0 | 0 |
| Energy Enhanced Malt Beverage | 0 | 0 | 0 | 0 | 0 |
| English Cider | 0 | 0 | 0 | 0 | 0 |
| English-Style Dark Mild Ale | 0 | 0 | 0 | 0 | 0 |
| English-Style Pale Mild Ale | 0 | 0 | 0 | 0 | 0 |
| English-Style Summer Ale | 0 | 0 | 0 | 0 | 0 |
| European-Style Dark / Münchner Dunkel | 0 | 0 | 0 | 0 | 0 |
| Field Beer | 0 | 0 | 0 | 0 | 0 |
| Flavored Malt Beverage | 0 | 0 | 0 | 0 | 0 |
| French Cider | 0 | 0 | 0 | 0 | 0 |
| French-Style Bière de Garde | 0 | 0 | 0 | 0 | 0 |
| Fresh "Wet" Hop Ale | 0 | 0 | 0 | 0 | 0 |
| Fruit Beer | 0 | 0 | 0 | 0 | 0 |
| Fruit Cider | 0 | 0 | 0 | 0 | 0 |
| German-Style Doppelbock | 0 | 0 | 0 | 0 | 0 |
| German-Style Eisbock | 0 | 0 | 0 | 0 | 0 |
| German-Style Heller Bock/Maibock | 0 | 0 | 0 | 0 | 0 |
| German-Style Leichtbier | 0 | 0 | 0 | 0 | 0 |
| German-Style Leichtes Weizen / Weissbier | 0 | 0 | 0 | 0 | 0 |
| German-Style Märzen | 0 | 0 | 0 | 0 | 0 |
| German-Style Oktoberfest / Wiesen (Meadow) | 0 | 0 | 0 | 0 | 0 |
| German-Style Rye Ale (Roggenbier) with or without Yeast | 0 | 0 | 0 | 0 | 0 |
| German-Style Schwarzbier | 0 | 0 | 0 | 0 | 0 |
| Ginjo Beer or Sake-Yeast Beer | 0 | 0 | 0 | 0 | 0 |
| Gluten-Free Beer | 0 | 0 | 0 | 0 | 0 |
| Grodziskie | 0 | 0 | 0 | 0 | 0 |
| Herb and Spice Beer | 0 | 0 | 0 | 0 | 0 |
| Historical Beer | 0 | 0 | 0 | 0 | 0 |
| India Pale Ale | 2 | 48 | 10 | 17 | 500 |
| Kellerbier (Cellar beer) or Zwickelbier - Ale | 0 | 0 | 0 | 0 | 0 |
| Kölsch | 0 | 0 | 0 | 0 | 0 |
| Lager | 0 | 0 | 0 | 0 | 0 |
| Leipzig-Style Gose | 0 | 0 | 0 | 0 | 0 |
| Metheglin | 0 | 0 | 0 | 0 | 0 |
| Mixed Culture Brett Beer | 0 | 0 | 0 | 0 | 0 |
| Münchner (Munich)-Style Helles | 0 | 0 | 0 | 0 | 0 |
| New England Cider | 0 | 0 | 0 | 0 | 0 |
| Non-Alcoholic (Beer) Malt Beverages | 0 | 0 | 0 | 0 | 0 |
| Old Ale | 0 | 0 | 0 | 0 | 0 |
| Open Category Mead | 0 | 0 | 0 | 0 | 0 |
| Other Belgian-Style Ales | 0 | 0 | 0 | 0 | 0 |
| Other Fruit Melomel | 0 | 0 | 0 | 0 | 0 |
| Other Specialty Cider or Perry | 0 | 0 | 0 | 0 | 0 |
| Pale Ale | 0 | 0 | 0 | 0 | 0 |
| Pale American-Belgo-Style Ale | 0 | 0 | 0 | 0 | 0 |
| Pilsener | 0 | 0 | 0 | 0 | 0 |
| Porter | 0 | 0 | 0 | 0 | 0 |
| Pumpkin Beer | 0 | 0 | 0 | 0 | 0 |
| Pyment (Grape Melomel) | 0 | 0 | 0 | 0 | 0 |
| Red | 0 | 0 | 0 | 0 | 0 |
| Saison | 0 | 0 | 0 | 0 | 0 |
| Scotch Ale | 0 | 0 | 0 | 0 | 0 |
| Scottish-Style Export Ale | 0 | 0 | 0 | 0 | 0 |
| Scottish-Style Heavy Ale | 0 | 0 | 0 | 0 | 0 |
| Scottish-Style Light Ale | 0 | 0 | 0 | 0 | 0 |
| Semi-Sweet Mead | 0 | 0 | 0 | 0 | 0 |
| Session Beer | 0 | 0 | 0 | 0 | 0 |
| Sour | 0 | 0 | 0 | 0 | 0 |
| South German-Style Bernsteinfarbenes Weizen / Weissbier | 0 | 0 | 0 | 0 | 0 |
| South German-Style Dunkel Weizen / Dunkel Weissbier | 0 | 0 | 0 | 0 | 0 |
| South German-Style Kristall Weizen / Kristall Weissbier | 0 | 0 | 0 | 0 | 0 |
| South German-Style Weizenbock / Weissbock | 0 | 0 | 0 | 0 | 0 |
| Specialty Beer | 0 | 0 | 0 | 0 | 0 |
| Stout | 58 | 6 | 135 | 0 | 4 |
| Strong Ale | 0 | 0 | 0 | 0 | 0 |
| Sweet Mead | 0 | 0 | 0 | 0 | 0 |
| Traditional German-Style Bock | 0 | 0 | 0 | 0 | 0 |
| Traditional Perry | 0 | 0 | 0 | 0 | 0 |
| Tripel | 3 | 3 | 1 | 0 | 58 |
| Wheat | 3 | 287 | 5 | 9 | 13 |
| Wild Beer | 0 | 0 | 0 | 0 | 0 |
Now that we have a manageable number of styles, we can see how well fit each cluster is to each style. If the features we clustered on perfectly predicted style, there would each color (cluster) would be unique to each facet of the plot. (E.g., left entirely blue, second from left entirely green, etc.)
by_style_plot <- ggplot() +
geom_point(data = certain_styles_clustered,
aes(x = abv, y = ibu,
colour = cluster_assignment), alpha = 0.5) +
facet_grid(. ~ style_collapsed) +
geom_point(data = style_centers_certain_styles,
aes(mean_abv, mean_ibu), colour = "black", shape = 5) +
ggtitle("Selected Styles Cluster Assignment") +
labs(x = "ABV", y = "IBU") +
labs(colour = "Cluster") +
theme_bw()
by_style_plot
–>
Do more hops always mean more bitterness?
ggplot(data = beer_ingredients_join, aes(total_hops, ibu)) +
geom_point(aes(total_hops, ibu, colour = style_collapsed)) +
geom_smooth(method = lm, se = FALSE, colour = "black") +
ggtitle("Hops Per Beer vs. Bitterness") +
labs(x = "Number of Hops", y = "IBU", colour = "Style Collapsed") +
theme_minimal()
hops_ibu_lm <- lm(ibu ~ total_hops, data = beer_ingredients_join)
summary(hops_ibu_lm)
Call:
lm(formula = ibu ~ total_hops, data = beer_ingredients_join)
Residuals:
Min 1Q Median 3Q Max
-39.95 -18.95 -7.25 14.92 959.05
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 40.95273 0.18040 227.008 < 2e-16 ***
total_hops 0.22822 0.06661 3.426 0.000613 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 26.97 on 23117 degrees of freedom
(40376 observations deleted due to missingness)
Multiple R-squared: 0.0005076, Adjusted R-squared: 0.0004644
F-statistic: 11.74 on 1 and 23117 DF, p-value: 0.0006126
ggplot(data = beer_ingredients_join[which(beer_ingredients_join$total_hops > 2
& beer_ingredients_join$total_hops < 8), ], aes(total_hops, ibu)) +
geom_point(aes(total_hops, ibu, colour = style_collapsed)) +
geom_smooth(method = lm, se = FALSE, colour = "black") +
ggtitle("3+ Hops Per Beer vs. Bitterness") +
labs(x = "Number of Hops", y = "IBU", colour = "Style Collapsed") +
theme_minimal()
Most popular hops
# Gather up all the hops columns into one called `hop_name`
beer_necessities_hops_gathered <- beer_necessities %>%
gather(
hop_key, hop_name, hops_name_1:hops_name_13
) %>% as_tibble()
# Filter to just those beers that have at least one hop
beer_necessities_w_hops <- beer_necessities_hops_gathered %>%
filter(!is.na(hop_name)) %>%
filter(!hop_name == "")
beer_necessities_w_hops$hop_name <- factor(beer_necessities_w_hops$hop_name)
# For all hops, find the number of beers they're in as well as those beers' mean IBU and ABV
hops_beer_stats <- beer_necessities_w_hops %>%
ungroup() %>%
group_by(hop_name) %>%
summarise(
mean_ibu = mean(ibu, na.rm = TRUE),
mean_abv = mean(abv, na.rm = TRUE),
n = n()
)
# Pare to hops that are used in at least 50 beers
pop_hops_beer_stats <- hops_beer_stats[hops_beer_stats$n > 50, ]
kable(pop_hops_beer_stats)
| hop_name | mean_ibu | mean_abv | n |
|---|---|---|---|
| Amarillo | 61.36053 | 6.959264 | 163 |
| Cascade | 51.92405 | 6.510729 | 445 |
| Centennial | 63.96526 | 7.081883 | 243 |
| Chinook | 60.86871 | 7.043439 | 194 |
| Citra | 59.60000 | 6.733290 | 157 |
| Columbus | 63.74483 | 6.953846 | 183 |
| East Kent Golding | 38.51875 | 6.347386 | 89 |
| Fuggles | 40.75581 | 6.772143 | 59 |
| Hallertauer (American) | 23.92388 | 5.658537 | 83 |
| Magnum | 48.71596 | 6.926852 | 109 |
| Mosaic | 56.81818 | 6.977465 | 71 |
| Mount Hood | 37.83500 | 6.550000 | 68 |
| Northern Brewer (American) | 39.48475 | 6.473944 | 71 |
| Nugget | 52.23810 | 6.383119 | 114 |
| Perle (American) | 32.03947 | 6.251744 | 88 |
| Saaz (American) | 30.69778 | 6.248333 | 60 |
| Simcoe | 64.07211 | 6.877394 | 191 |
| Sterling | 35.41860 | 6.024259 | 55 |
| Tettnanger (American) | 30.27551 | 6.016780 | 59 |
| Warrior | 59.13043 | 6.983115 | 62 |
| Willamette | 39.61078 | 7.014657 | 133 |
# Keep just beers that contain these most popular hops
beer_necessities_w_popular_hops <- beer_necessities_w_hops %>%
filter(hop_name %in% pop_hops_beer_stats$hop_name) %>%
droplevels()
Are there certian hops that are used more often in very high IBU or ABV beers? Hard to detect a pattern
ggplot(data = beer_necessities_w_popular_hops) +
geom_point(aes(abv, ibu, colour = hop_name)) +
ggtitle("Beers Containing most Popular Hops") +
labs(x = "ABV", y = "IBU", colour = "Hop Name") +
theme_minimal()
ggplot(data = pop_hops_beer_stats) +
geom_point(aes(mean_abv, mean_ibu, colour = hop_name, size = n)) +
ggtitle("Most Popular Hops' Effect on Alcohol and Bitterness") +
labs(x = "Mean ABV per Hop Type", y = "Mean IBU per Hop Type", colour = "Hop Name",
size = "Number of Beers") +
theme_minimal()
style or style_collapsed?style or style_collapsed; the one not specified as outcome will be droppedpredictor_varslibrary(nnet)
library(caret)
run_neural_net <- function(df, outcome, predictor_vars) {
out <- list(outcome = outcome)
# Create a new column outcome; it's style_collapsed if you set outcome to style_collapsed, and style otherwise
if (outcome == "style_collapsed") {
df[["outcome"]] <- df[["style_collapsed"]]
} else {
df[["outcome"]] <- df[["style"]]
}
df$outcome <- factor(df$outcome)
cols_to_keep <- c("outcome", predictor_vars)
df <- df %>%
select_(.dots = cols_to_keep) %>%
mutate(row = 1:nrow(df)) %>%
droplevels()
# Select 80% of the data for training
df_train <- sample_n(df, nrow(df)*(0.8))
# The rest is for testing
df_test <- df %>%
filter(! (row %in% df_train$row)) %>%
select(-row)
df_train <- df_train %>%
select(-row)
# Build multinomail neural net
nn <- multinom(outcome ~ .,
data = df_train, maxit=500, trace=T)
# Which variables are the most important in the neural net?
most_important_vars <- varImp(nn)
# How accurate is the model? Compare predictions to outcomes from test data
nn_preds <- predict(nn, type="class", newdata = df_test)
nn_accuracy <- postResample(df_test$outcome, nn_preds)
out <- list(out, nn = nn, most_important_vars = most_important_vars,
df_test = df_test,
nn_preds = nn_preds,
nn_accuracy = nn_accuracy)
return(out)
}
beer_totals, the predictor variables to be the vector contained in p_vars, the outcome to be style_collapsedTake out NAs
bt_omit <- beer_totals %>% na.omit()
p_vars <- c("total_hops", "total_malt", "abv", "ibu", "srm")
nn_collapsed_out <- run_neural_net(df = bt_omit, outcome = "style_collapsed",
predictor_vars = p_vars)
# weights: 266 (222 variable)
initial value 800.268955
iter 10 value 606.966534
iter 20 value 557.180737
iter 30 value 527.003811
iter 40 value 510.870829
iter 50 value 495.376651
iter 60 value 458.207968
iter 70 value 408.305952
iter 80 value 376.270666
iter 90 value 354.949715
iter 100 value 341.937012
iter 110 value 324.405452
iter 120 value 313.536578
iter 130 value 306.739580
iter 140 value 301.423593
iter 150 value 296.559338
iter 160 value 293.432943
iter 170 value 291.671564
iter 180 value 290.220037
iter 190 value 289.370752
iter 200 value 288.691856
iter 210 value 287.792355
iter 220 value 287.185759
iter 230 value 286.365962
iter 240 value 285.842047
iter 250 value 285.600407
iter 260 value 285.448644
iter 270 value 285.273483
iter 280 value 285.055191
iter 290 value 284.832262
iter 300 value 284.692212
iter 310 value 284.614784
iter 320 value 284.574410
iter 330 value 284.549547
iter 340 value 284.522034
iter 350 value 284.500604
iter 360 value 284.463509
iter 370 value 284.418475
iter 380 value 284.368603
iter 390 value 284.320421
iter 400 value 284.238956
iter 410 value 284.158280
iter 420 value 284.078921
iter 430 value 284.001264
iter 440 value 283.904806
iter 450 value 283.865220
iter 460 value 283.859244
iter 470 value 283.853966
iter 480 value 283.848464
iter 490 value 283.837598
iter 500 value 283.820386
final value 283.820386
stopped after 500 iterations
# How accurate was it?
nn_collapsed_out$nn_accuracy
Accuracy Kappa
0.4000000 0.3452641
# What were the most important variables?
nn_collapsed_out$most_important_vars
style instead of style_collapsed?
nn_notcollapsed_out <- run_neural_net(df = bt_omit, outcome = "style",
predictor_vars = p_vars)
nn_notcollapsed_out$nn_accuracy
nn_notcollapsed_out$most_important_vars
And now if we add glass as a predictor?
p_vars_add_glass <- c("total_hops", "total_malt", "abv", "ibu", "srm", "glass")
nn_collapsed_out_add_glass <- run_neural_net(df = beer_ingredients_join, outcome = "style_collapsed",
predictor_vars = p_vars_no_glass)
nn_collapsed_out_add_glass$nn_accuracy
nn_collapsed_out_add_glass$most_important_vars
ranger package is built to handle sparse data like thisglass as a predictorlibrary(ranger)
library(stringr)
bi <- beer_ingredients_join %>%
select(-c(id, name, style, hops_name, malt_name,
# description,
glass)) %>%
mutate(row = 1:nrow(.)) %>%
na.omit()
bi$style_collapsed <- factor(bi$style_collapsed)
# ranger complains about special characters and spaces in ingredient column names. Take them out and replace with empty string.
names(bi) <- tolower(names(bi))
names(bi) <- str_replace_all(names(bi), " ", "")
names(bi) <- str_replace_all(names(bi), "([\\(\\)-\\/')]+)", "")
# Keep 80% for training
bi_train <- sample_n(bi, nrow(bi)*(0.8))
# The rest is for testing
bi_test <- bi %>%
filter(! (row %in% bi_train$row)) %>%
dplyr::select(-row)
bi_train <- bi_train %>%
dplyr::select(-row) %>%
select(-`#06300`)
bi_rf <- ranger(style_collapsed ~ ., data = bi_train, importance = "impurity", seed = 11)
OOB (out of bag) prediction error is around 58% * This calculated from tree samples constructed but not used in training set; these trees become effectively part of test set
bi_rf
We can compare predicted classification on the test set to their actual style classification.
pred_bi_rf <- predict(bi_rf, dat = bi_test)
table(bi_test$style_collapsed, pred_bi_rf$predictions)
Variable importance * Interestingly, ABV, IBU, and SRM are all much more important in the random forest than total_hops and total_malt
importance(bi_rf)[1:10]
How does a CSRF (case-specific random forest) fare?
bi_csrf <- csrf(style_collapsed ~ ., training_data = bi_train, test_data = bi_test,
params1 = list(num.trees = 5, mtry = 4),
params2 = list(num.trees = 2))
csrf_acc <- postResample(bi_csrf, bi_test$style_collapsed)
csrf_acc
Style first, forgiveness later?
Future Directions